package com.seed.core.query;

public class SeedSet {
//    public static GetVO get(Seed seed, Object id, String declare) {
//        String tableName = seed.getTableName();
//        String selfNameColumn = SeedKit.getNameColumn(seed);
//        Declared declared = SeedKit.getDeclared(seed, declare);
//        PropertyType propertyType = declared.getType();
//        if(propertyType == PropertyType.column) {
//            Row one =  DbChain.table(tableName)
//                    .select(Const.ID, declare, selfNameColumn)
//                    .where(Const.ID + " = ?", id)
//                    .one();
//            if(one == null) throw new RuntimeException("数据不存在");
//
//            return new GetVO((String) id, one.getString(selfNameColumn), PropertyType.column, one.get(declare));
//        }
//
//        if(propertyType == PropertyType.belongsTo) {
//            BelongsTos belongsTo = (BelongsTos) declared.getProperty();
//            String inferSelfColumn = belongsTo.inferSelfColumn();
//            String inferTargetColumn = belongsTo.inferTargetColumn();
//            Row one = DbChain.table(tableName)
//                    .select(Const.ID, inferSelfColumn, selfNameColumn)
//                    .where(Const.ID + " = ?", id)
//                    .one();
//            if(one == null) throw new RuntimeException("数据不存在");
//
//            Object selfValue = one.get(inferSelfColumn);
//            if(selfValue == null) return new GetVO((String) id, one.getString(selfNameColumn), PropertyType.belongsTo);
//
//            Seed targetSeed = belongsTo.targetSeed();
//            String targetTableName = targetSeed.getTableName();
//            String targetNameColumn = SeedKit.getNameColumn(targetSeed);
//            Row target = DbChain.table(targetTableName)
//                    .select(inferTargetColumn, targetNameColumn)
//                    .where(new QueryColumn(new QueryTable(targetTableName), inferTargetColumn).eq(selfValue))
//                    .one();
//            if(target == null) throw new RuntimeException("引用的对象不存在");
//
//            String targetName = target.getString(targetNameColumn);
//            return new GetVO((String) id, one.getString(selfNameColumn), PropertyType.belongsTo, selfValue, targetName);
//        }
//
//        if(propertyType == PropertyType.hasOne) {
//            throw new RuntimeException("未实现");
//        }
//
//        if(propertyType == PropertyType.hasMany) {
//            throw new RuntimeException("未实现");
//        }
//
//        Habtms habtm = (Habtms) declared.getProperty();
//        String inferSelfColumn = habtm.inferSelfColumn();
//        String inferThroughSelfColumn = habtm.inferThroughSelfColumn();
//        String inferThroughTargetColumn = habtm.inferThroughTargetColumn();
//        String inferTargetColumn = habtm.inferTargetColumn();
//        String throughTableName = habtm.throughTableName();
//        Row one = DbChain.table(tableName).select(inferSelfColumn, selfNameColumn).where(Const.ID + " = ?", id).one();
//        if(one == null) throw new RuntimeException("数据不存在");
//
//        Object selfValue = one.get(inferSelfColumn);
//        if(selfValue == null) throw new RuntimeException(String.format("【%s】值为空，不合法", inferSelfColumn));
//
//        List<Row> throughList = DbChain.table(throughTableName)
//                .select(inferThroughTargetColumn)
//                .where(inferThroughSelfColumn + " = ?", selfValue)
//                .list();
//        Object[] targetIds = throughList.stream().map(e -> e.get(inferThroughTargetColumn)).toArray();
//
//        Seed targetSeed = habtm.targetSeed();
//        String targetTableName = targetSeed.getTableName();
//        String nameColumn = SeedKit.getNameColumn(targetSeed);
//        List<Row> targetList = targetIds.length > 0
//                ? DbChain.table(targetTableName).select(inferTargetColumn, nameColumn)
//                    .where(new QueryColumn(new QueryTable(targetTableName), inferTargetColumn).in(targetIds))
//                    .list()
//                : Collections.emptyList();
//
//        Map<Object, String> ret = new HashMap<>();
//        for(Object targetId: targetIds) {
//            Optional<Row> optional = targetList
//                    .stream()
//                    .filter(e -> targetId.equals(e.get(inferTargetColumn)))
//                    .findFirst();
//            if(optional.isEmpty()) throw new RuntimeException("引用的对象不存在");
//
//            Row first = optional.get();
//            ret.put(targetId, first.getString(nameColumn));
//        }
//
//        return new GetVO((String) id, one.getString(selfNameColumn), PropertyType.habtm, ret);
////        StringBuilder sb = new StringBuilder();
////        for(Row row: throughList) {
////            Object val = row.get(inferThroughTargetColumn);
////            if(val == null) continue;
////
////            if(!sb.isEmpty()) sb.append(',');
////            sb.append(val);
////        }
////
////        return sb.toString();
//    }
//
////    public static void reset(Seed seed, Object id, String columnName, String columnValue) {
////        if(StrUtil.isBlank(columnName)) columnName = Const.PASSWORD;
////        if(StrUtil.isBlank(columnValue)) columnValue = Const.INIT_PASSWORD_VALUE;
////        columnName = StrUtil.toUnderlineCase(columnName);
////        String saltColumnName = StrUtil.replace(columnName, Const.PASSWORD, Const.SALT);
////        String salt = UUID.fastUUID().toString();
////        String encrypt = EncryptUtil.encrypt(columnValue, salt);
////
////        String tableName = seed.getTableName();
////        Declared declared = Micro.getDeclared(seed, columnName);
////        PropertyType propertyType = declared.getType();
////        if (propertyType != PropertyType.column) throw new RuntimeException("密码重置只支持列操作");
////
////        Row row = DbChain.table(tableName).select(Const.ID, columnName).where(Const.ID + " = ?", id).one();
////        if (row == null) throw new RuntimeException("数据不存在");
////
////        DbChain.table(tableName).set(columnName, encrypt).set(saltColumnName, salt).where("id = ?", id).update();
////    }
//
//    public static void set(Seed seed, Object id, String declare, String declareValue) {
//        String tableName = seed.getTableName();
//        if(StrUtil.isBlank(declareValue)) declareValue = null;
//
//        Declared declared = SeedKit.getDeclared(seed, declare);
//        PropertyType propertyType = declared.getType();
//        switch (propertyType) {
//            case column -> {
//                Row row = DbChain.table(tableName).select(Const.ID, declare).where(Const.ID + " = ?", id).one();
//                if(row == null) throw new RuntimeException("数据不存在");
//
//                if(StrUtil.equals(declareValue, row.getString(declare))) return;
//                Column column = (Column) declared.getProperty();
//                Row data = new Row().set(Const.ID, id).set(StrUtil.toCamelCase(declare), declareValue);
//                SeedValidator.validate(seed, column, data);
//                DbChain.table(tableName).set(declare, declareValue).where(Const.ID + " = ?", id).update();
//            }
//            case belongsTo -> {
//                BelongsTos belongsTo = (BelongsTos) declared.getProperty();
//                String inferSelfColumn = belongsTo.inferSelfColumn();
//                Row row = DbChain.table(tableName).select(Const.ID, inferSelfColumn).where(Const.ID + " = ?", id).one();
//                if(row == null) throw new RuntimeException("数据不存在");
//
//                if(StrUtil.equals(declareValue, row.getString(inferSelfColumn))) return;
//                DbChain.table(tableName).set(inferSelfColumn, declareValue).where(Const.ID + " = ?", id).update();
//            }
//            case hasOne -> {
////                TODO
//                HasOnes hasOne = (HasOnes) declared.getProperty();
//                Seed targetSeed = hasOne.targetSeed();
//                String inferSelfColumn = hasOne.inferSelfColumn();
//                String inferTargetColumn = hasOne.inferTargetColumn();
//                String targetTableName = targetSeed.getTableName();
//
//                Row row = DbChain.table(tableName).select(inferSelfColumn).where(Const.ID + " = ?", id).one();
//                if(row == null) throw new RuntimeException("数据不存在");
//
//                Column refColumn = getRefColumn(targetSeed, inferTargetColumn);
//                if(refColumn == null) throw new RuntimeException("不能接管目标列");
//
//                Object selfValue = row.get(inferSelfColumn);
//                if(selfValue == null) throw new RuntimeException(String.format("【%s】值为空，不合法", inferSelfColumn));
//
//                DbChain.table(targetTableName).where(inferTargetColumn + " = ?", selfValue).remove();
//                if(StrUtil.isBlank(declareValue)) return;
//
//                Row ret = Row.ofKey(RowKey.FLEX_ID);
//                ret.set(inferTargetColumn, selfValue);
//                ret.set(refColumn.getName(), declareValue);
//                Db.insert(targetTableName, ret);
//            }
//            case hasMany -> {
//                HasManys hasMany = (HasManys) declared.getProperty();
////                ExtraType extraType = hasMany.getExtraType();
////                if(extraType == ExtraType.code) throw new RuntimeException("一对多关系不支持【code】类型");
//                Map<String, Object> extra = hasMany.getExtra();
//
//                Seed targetSeed = hasMany.targetSeed();
//                String inferSelfColumn = hasMany.inferSelfColumn();
//                String inferTargetColumn = hasMany.inferTargetColumn();
//                String targetTableName = targetSeed.getTableName();
//
//                Row row = DbChain.table(tableName).select(inferSelfColumn).where(Const.ID + " = ?", id).one();
//                if(row == null) throw new RuntimeException("数据不存在");
//
//                Column refColumn = getRefColumn(targetSeed, inferTargetColumn);
//                Object selfValue = row.get(inferSelfColumn);
//                if(selfValue == null) throw new RuntimeException(String.format("【%s】值为空，不合法", inferSelfColumn));
//
//                QueryCondition condition = new RawQueryCondition(inferTargetColumn + " = ?", selfValue);
//                if(extra != null) {
//                    for(Map.Entry<String, Object> entry: extra.entrySet()) {
//                        condition.and(entry.getKey() + " = ?", entry.getValue());
//                    }
//                }
//                DbChain.table(targetTableName).where(condition).remove();
//
//                if(StrUtil.isBlank(declareValue)) return;
//
//                List<String> targetValues = Arrays.stream(declareValue.split(",")).map(String::trim).distinct().toList();
//                List<Row> adding = new ArrayList<>();
//                for(String targetValue: targetValues) {
//                    Row ret = Row.ofKey(RowKey.FLEX_ID);
//                    ret.set(inferTargetColumn, selfValue);
//                    ret.set(refColumn.getName(), targetValue);
//                    if(extra != null) {
//                        for(Map.Entry<String, Object> entry: extra.entrySet()) {
//                            ret.set(entry.getKey(), entry.getValue());
//                        }
//                    }
//                    adding.add(ret);
//                }
//                Db.insertBatch(targetTableName, adding);
//            }
//            case habtm -> {
//                Habtms habtm = (Habtms) declared.getProperty();
////                ExtraType extraType = habtm.getExtraType();
////                if(extraType == ExtraType.code) throw new RuntimeException("多对多关系不支持【code】类型");
//                Map<String, Object> extra = habtm.getExtra();
//
//                String inferSelfColumn = habtm.inferSelfColumn();
//                String inferThroughSelfColumn = habtm.inferThroughSelfColumn();
//                String inferThroughTargetColumn = habtm.inferThroughTargetColumn();
//                String throughTableName = habtm.throughTableName();
//                Row row = DbChain.table(tableName).select(inferSelfColumn).where(Const.ID + " = ?", id).one();
//                if(row == null) throw new RuntimeException("数据不存在");
//
//                Object selfValue = row.get(inferSelfColumn);
//                if(selfValue == null) throw new RuntimeException(String.format("【%s】值为空，不合法", inferSelfColumn));
//
//                QueryCondition condition = new RawQueryCondition(inferThroughSelfColumn + " = ?", selfValue);
//                if(extra != null) {
//                    for(Map.Entry<String, Object> entry: extra.entrySet()) {
//                        condition.and(entry.getKey() + " = ?", entry.getValue());
//                    }
//                }
//                DbChain.table(throughTableName).where(condition).remove();
//
//                if(StrUtil.isBlank(declareValue)) return;
//
//                List<String> targetValues = Arrays.stream(declareValue.split(",")).map(String::trim).distinct().toList();
//                List<Row> adding = new ArrayList<>();
//                for(String targetValue: targetValues) {
//                    Row ret = Row.ofKey(RowKey.FLEX_ID);
//                    ret.set(inferThroughSelfColumn, selfValue);
//                    ret.set(inferThroughTargetColumn, targetValue);
//                    if(extra != null) {
//                        for(Map.Entry<String, Object> entry: extra.entrySet()) {
//                            ret.set(entry.getKey(), entry.getValue());
//                        }
//                    }
//                    adding.add(ret);
//                }
//                Db.insertBatch(throughTableName, adding);
//            }
//            default -> throw new RuntimeException("列名不支持【空】或【*】配置");
//        }
//    }
//
//    private static Column getRefColumn(Seed seed, String throughSelfColumn) {
//        LinkedHashMap<String, Column> columns = seed.getColumns();
//        if(columns == null || columns.isEmpty()) return null;
//
//        List<Column> ret = new ArrayList<>();
//        for(Map.Entry<String, Column> entry: columns.entrySet()) {
//            String columnName = entry.getKey();
//            if(List.of("id", "tenant_id", "created_at", "updated_at", "deleted_at", "version", throughSelfColumn).contains(columnName)) continue;
//
//            ret.add(entry.getValue());
//        }
//
//        // 只有一列，并且是引用类型的列，说明这个表是一个关系表
////        List<Column> refColumns = ret.stream().filter(e -> e.getType() == ColumnType.REF).toList();
////        if(refColumns.size() != 1) throw new RuntimeException("多个引用列产生歧义，不能接管目标列");
//
////        return refColumns.get(0);
//        throw new RuntimeException("TODO");
//    }

//    public static void setForRow(Seed seed, Map<String, Declared> declareds, String columnName, String columnValue, Row self) {
//        Object id = self.get(Const.ID);
//        String fieldName = StrUtil.toCamelCase(columnName);
//        String tableName = seed.getTableName();
//        SeedContext context = SeedManager.get();
//        String declare = StrUtil.toUnderlineCase(columnName);
//        Map<String, Declared> columnDeclareds = context.buildDeclared(seed, declare);
//        Declared declared = columnDeclareds.get(declare);
//        PropertyType propertyType = declared.getType();
//        switch (propertyType) {
//            case column -> {
//                Object value = StrUtil.isBlank(columnValue) ? self.get(fieldName) : columnValue;
//                DbChain.table(tableName).set(declare, value).where("id = ?", id).update();
//            }
//            case belongsTo -> {
//                BelongsTos belongsTo = (BelongsTos) declared.getProperty();
//                String inferSelfColumn = belongsTo.inferSelfColumn();
//                Object value = self.get(StrUtil.toCamelCase(inferSelfColumn));
//                DbChain.table(tableName).set(inferSelfColumn, value).where("id = ?", id).update();
//            }
//            case hasOne -> {
//                HasOnes hasOne = (HasOnes) declared.getProperty();
//                Seed targetSeed = hasOne.targetSeed();
//                String inferSelfColumn = hasOne.inferSelfColumn();
//                String inferTargetColumn = hasOne.inferTargetColumn();
//                Object selfValue = self.get(StrUtil.toCamelCase(inferSelfColumn));
//                String targetTableName = targetSeed.getTableName();
//
//                Row one = DbChain.table(targetTableName).where(inferTargetColumn + " = ?", selfValue).one();
//                Map<String, Object> targetObj = (Map<String, Object>) self.get(fieldName);
//                if(targetObj == null) {
//                    if(one != null) SeedUpdate.removeOne(hasOne, one);
//                } else {
//                    targetObj.put(StrUtil.toCamelCase(inferTargetColumn), self.get(StrUtil.toCamelCase(inferSelfColumn)));
//                    if(one == null) {
//                        SeedSave.save(targetSeed, declareds, targetObj);
//                    } else {
//                        targetObj.put(Const.ID, one.get(Const.ID));
//                        SeedUpdate.update(targetSeed, declareds, targetObj);
//                    }
//                }
//            }
//            case hasMany -> {
//                // TODO
//            }
//            case habtm -> {
//                Habtms habtm = (Habtms) declared.getProperty();
//                String inferSelfColumn = habtm.inferSelfColumn();
//                String inferTargetColumn = habtm.inferTargetColumn();
//                String inferThroughSelfColumn = habtm.inferThroughSelfColumn();
//                String inferThroughTargetColumn = habtm.inferThroughTargetColumn();
//                String throughTableName = habtm.throughTableName();
//                Object selfValue = self.get(StrUtil.toCamelCase(inferSelfColumn));
//                DbChain.table(throughTableName).where(inferThroughSelfColumn + " = ?", selfValue).remove();
//
//                Object targetObj = self.get(fieldName);
//                Collection<Row> target;
//                if(targetObj.getClass().isArray()) {
//                    target = List.of((Row[]) targetObj);
//                } else if(targetObj instanceof Collection<?>) {
//                    target = (Collection<Row>) targetObj;
//                } else {
//                    throw new RuntimeException(String.format("不支持的类型【%s】", targetObj.getClass()));
//                }
//
//                List<Row> adding = new ArrayList<>();
//                for(Row row: target) {
//                    Row ret = Row.ofKey(RowKey.FLEX_ID);
//                    ret.set(inferThroughSelfColumn, selfValue);
//                    ret.set(inferThroughTargetColumn, row.get(StrUtil.toCamelCase(inferTargetColumn)));
//                    adding.add(ret);
//                }
//                if(!adding.isEmpty()) Db.insertBatch(throughTableName, adding);
//            }
//            default -> throw new RuntimeException("列名不支持【空】或【*】配置");
//        }
//    }

//    public static <T> void setForObject(Seed seed, Map<String, Declared> declareds, String columnName, String columnValue, T self) {
//        Object id = ReflectUtil.getFieldValue(self, Const.ID);
//        String fieldName = StrUtil.toCamelCase(columnName);
//        String tableName = seed.getTableName();
//        SeedContext context = SeedManager.get();
//        String declare = StrUtil.toUnderlineCase(columnName);
//        Map<String, Declared> columnDeclareds = context.buildDeclared(seed, declare);
//        Declared declared = columnDeclareds.get(declare);
//        PropertyType propertyType = declared.getType();
//        switch (propertyType) {
//            case column -> {
//                Object value = StrUtil.isBlank(columnValue) ? ReflectUtil.getFieldValue(self, fieldName) : columnValue;
//                DbChain.table(tableName).set(declare, value).where("id = ?", id).update();
//            }
//            case belongsTo -> {
//                BelongsTos belongsTo = (BelongsTos) declared.getProperty();
//                String inferSelfColumn = belongsTo.inferSelfColumn();
//                Object value = ReflectUtil.getFieldValue(self, StrUtil.toCamelCase(inferSelfColumn));
//                DbChain.table(tableName).set(inferSelfColumn, value).where("id = ?", id).update();
//            }
//            case hasOne -> {
//                HasOnes hasOne = (HasOnes) declared.getProperty();
//                Seed targetSeed = hasOne.targetSeed();
//                String inferSelfColumn = hasOne.inferSelfColumn();
//                String inferTargetColumn = hasOne.inferTargetColumn();
//                Object selfValue = ReflectUtil.getFieldValue(self, StrUtil.toCamelCase(inferSelfColumn));
//                String targetTableName = targetSeed.getTableName();
//
//                Row one = DbChain.table(targetTableName).where(inferTargetColumn + " = ?", selfValue).one();
//                Object targetObj = ReflectUtil.getFieldValue(self, fieldName);
//                if(targetObj == null) {
//                    if(one != null) SeedUpdate.removeOne(hasOne, one);
//                } else {
//                    ReflectUtil.setFieldValue(targetObj, StrUtil.toCamelCase(inferTargetColumn), selfValue);
//                    if(one == null) {
//                        SeedSave.save(targetSeed, declareds, targetObj);
//                    } else {
//                        ReflectUtil.setFieldValue(targetObj, Const.ID, ReflectUtil.getFieldValue(one, Const.ID));
//                        SeedUpdate.update(targetSeed, declareds, targetObj);
//                    }
//                }
//            }
//            case hasMany -> {
//                // TODO
//            }
//            case habtm -> {
//                Habtms habtm = (Habtms) declared.getProperty();
//                String inferSelfColumn = habtm.inferSelfColumn();
//                String inferTargetColumn = habtm.inferTargetColumn();
//                String inferThroughSelfColumn = habtm.inferThroughSelfColumn();
//                String inferThroughTargetColumn = habtm.inferThroughTargetColumn();
//                String throughTableName = habtm.throughTableName();
//                Object selfValue = ReflectUtil.getFieldValue(self, StrUtil.toCamelCase(inferSelfColumn));
//                DbChain.table(throughTableName).where(inferThroughSelfColumn + " = ?", selfValue).remove();
//
//                Object targetObj = ReflectUtil.getFieldValue(self, fieldName);
//                Collection<Row> target;
//                if(targetObj.getClass().isArray()) {
//                    target = List.of((Row[]) targetObj);
//                } else if(targetObj instanceof Collection<?>) {
//                    target = (Collection<Row>) targetObj;
//                } else {
//                    throw new RuntimeException(String.format("不支持的类型【%s】", targetObj.getClass()));
//                }
//
//                List<Row> adding = new ArrayList<>();
//                for(Row row: target) {
//                    Row ret = Row.ofKey(RowKey.FLEX_ID);
//                    ret.set(inferThroughSelfColumn, selfValue);
//                    ret.set(inferThroughTargetColumn, row.get(StrUtil.toCamelCase(inferTargetColumn)));
//                    adding.add(ret);
//                }
//                if(!adding.isEmpty()) Db.insertBatch(throughTableName, adding);
//            }
//            default -> throw new RuntimeException("列名不支持【空】或【*】配置");
//        }
//    }
}
